package com.yang.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.yang.domain.Car;
import com.yang.domain.User;
import com.yang.domain.UserCarDetails;
import com.yang.domain.dto.user.LoginUser;
import com.yang.domain.dto.user.RegisterUser;
import com.yang.domain.dto.user.UserInfo;
import com.yang.handler.UserThreadLocal;
import com.yang.service.FileService;
import com.yang.service.UserCarDetailsService;
import com.yang.service.UserService;
import com.yang.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 不是菜鸡爱编程
 * @Date: 2024/02/16/21:25
 * @Description:
 */
@Slf4j
@RestController
@RequestMapping("user")
@Api(tags = "用户模块", value = "用户controller")
public class UserController {
    @Autowired
    private FileService fileService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserCarDetailsService userCarDetailsService;

    @ApiOperation("用户登录")
    @PostMapping("/login")
    public R login(@RequestBody LoginUser user) {
        return userService.login(user.getUsername(), user.getPassword());
    }

    @ApiOperation("用户注册")
    @PostMapping("/register")
    public R register(@RequestBody RegisterUser registerUser) {
        return userService.register(registerUser);
    }

    @ApiOperation("发送邮箱注册验证码")
    @GetMapping("/captcha/{email}")
    public R sendRegisterCaptcha(@PathVariable String email) {
        return userService.sendRegisterCaptcha(email);
    }

    @ApiOperation("修改头像")
    @PostMapping("/header")
    public R updateUserHeader(MultipartFile file) {
        User user = UserThreadLocal.get();
        String upload = fileService.upload(file);
        boolean update = userService.update(null, new LambdaUpdateWrapper<User>()
                .eq(User::getId, user.getId())
                .set(User::getHeader, upload));
        if(update){
            return R.ok("修改成功").setData(upload);
        }else{
            return R.error("修改失败");
        }
    }

    /**
     * 查询用户列表
     */
    @ApiOperation("查询用户列表")
    @GetMapping("/list")
    public R list(User user,@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(ObjUtil.isNotEmpty(user.getId()), User::getId, user.getId())
                .eq(ObjUtil.isNotEmpty(user.getUsername()), User::getUsername, user.getUsername())
                .eq(ObjUtil.isNotEmpty(user.getEmail()), User::getEmail, user.getEmail())
                .eq(ObjUtil.isNotEmpty(user.getGender()), User::getGender, user.getGender())
                .eq(ObjUtil.isNotEmpty(user.getHeader()), User::getHeader, user.getHeader())
                .eq(ObjUtil.isNotEmpty(user.getIsAdmin()), User::getIsAdmin, user.getIsAdmin())
                .eq(ObjUtil.isNotEmpty(user.getLastLoginTime()), User::getLastLoginTime, user.getLastLoginTime())
                .eq(ObjUtil.isNotEmpty(user.getNickName()), User::getNickName, user.getNickName())
                .eq(ObjUtil.isNotEmpty(user.getPassword()), User::getPassword, user.getPassword())
                .eq(ObjUtil.isNotEmpty(user.getUpdateBy()), User::getUpdateBy, user.getUpdateBy())
                .eq(ObjUtil.isNotEmpty(user.getUpdateTime()), User::getUpdateTime, user.getUpdateTime())
                .eq(ObjUtil.isNotEmpty(user.getDelFlag()), User::getDelFlag, user.getDelFlag());
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据
        if (checkIsAdmin()!=0) {
            wrapper.eq(User::getDelFlag, 0);
        }
        return R.ok().setData(userService.page(new Page<>(pageNum, pageSize), wrapper));
    }

    /**
     * 获取用户详细信息
     */
    @ApiOperation("获取用户详细信息")
    @GetMapping(value = "/{id}")
    public R getInfo(@PathVariable("id") Integer id) {
        MPJLambdaWrapper<User> wrapper = new MPJLambdaWrapper<User>()
                .selectAll(User.class)
                // 将用户信息映射到userList字段上
                .selectCollection(Car.class, User::getCarList)
                .leftJoin(UserCarDetails.class, UserCarDetails::getUserId, User::getId)
                .leftJoin(Car.class, Car::getCard, UserCarDetails::getCarCard)
                .eq(User::getId, id);
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据
        if (checkIsAdmin()!=0) {
            wrapper.eq(User::getDelFlag, 0);
        }
        return R.ok().setData(userService.selectJoinOne(User.class, wrapper));
    }

    /**
     * 新增用户
     */
    @ApiOperation("新增用户")
    @PostMapping
    public R add(@RequestBody User user) {
        // TODO 头像上传
        // 查询账号是否已经注册
        long countUsername = userService.count(new LambdaQueryWrapper<User>().eq(User::getUsername, user.getUsername()));
        if(countUsername>0){
            return R.error("账号已经注册");
        }
        // 查询邮箱是否已经绑定过账号
        long countEmail = userService.count(new LambdaQueryWrapper<User>().eq(User::getEmail, user.getEmail()));
        if(countEmail>0){
            return R.error("邮箱已经绑定过账号");
        }
        userService.save(user);
        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, user.getUsername()));
        ArrayList<UserCarDetails> userCarDetails = new ArrayList<>();
        List<Car> carList = user.getCarList();
        // 如果更新后绑定的用户信息不为空
        if(CollUtil.isNotEmpty(carList)){
            // 则收集用户id
            for (Car car : carList) {
                userCarDetails.add(new UserCarDetails(one.getId(),car.getCard()));
            }
        }
        userCarDetailsService.saveBatch(userCarDetails);
        return R.ok();
    }

    /**
     * 修改用户
     */
    @ApiOperation("修改用户")
    @PutMapping
    public R edit(@RequestBody User user) {
        // TODO 重置密码
        ArrayList<UserCarDetails> userCarDetails = new ArrayList<>();
        List<Car> carList = user.getCarList();
        // 如果更新后绑定的用户信息不为空
        if(CollUtil.isNotEmpty(carList)){
            // 则收集用户id
            for (Car car : carList) {
                userCarDetails.add(new UserCarDetails(user.getId(),car.getCard()));
            }
        }
        MPJLambdaWrapper<User> wrapper = new MPJLambdaWrapper<User>()
                .selectAll(User.class)
                // 将用户信息映射到userList字段上
                .selectCollection(Car.class, User::getCarList)
                .leftJoin(UserCarDetails.class, UserCarDetails::getUserId, User::getId)
                .leftJoin(Car.class, Car::getCard, UserCarDetails::getCarCard)
                .eq(User::getId, user.getId());
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据
        if (checkIsAdmin()!=0) {
            wrapper.eq(User::getDelFlag, 0);
        }
        // 更新前的车辆包括关联信息
        User beforeUpdateUser = userService.selectJoinOne(User.class, wrapper);
        List<Car> beforeUpdateCarList = beforeUpdateUser.getCarList();
        // 判断关联信息是否更新过
        if(!beforeUpdateCarList.equals(carList)){
            // 更新过关联信息
            userCarDetailsService.remove(new LambdaQueryWrapper<UserCarDetails>()
                    .eq(UserCarDetails::getUserId,user.getId())
                    .in(CollUtil.isNotEmpty(beforeUpdateCarList),
                            UserCarDetails::getCarCard,
                            // 收集更新前的绑定的用户id
                            beforeUpdateCarList.stream().map(Car::getCard).collect(Collectors.toList())));
            userCarDetailsService.saveBatch(userCarDetails);
        }
        return R.ok().setData(userService.update(user, new LambdaQueryWrapper<User>()
                .eq(User::getId, user.getId())));
    }

    /**
     * 删除用户
     */
    @ApiOperation("删除用户")
    @DeleteMapping("/{ids}")
    public R remove(@PathVariable Integer[] ids) {
        return R.ok().setData(userService.removeByIds(Arrays.asList(ids)));
    }

    @ApiOperation("查询用户列表")
    @GetMapping("/listAll")
    public R listAll() {
        return R.ok().setData(userService.list());
    }

    @ApiOperation("更新用户个人信息")
    @PutMapping("/userInfo/update")
    public R userInfoUpdate(@RequestBody UserInfo userInfo) {
        User user = UserThreadLocal.get();
        user.setNickName(userInfo.getNickName());
        user.setGender(userInfo.getGender());
        user.setEmail(userInfo.getEmail());
        return R.ok().setData(userService.updateById(user));
    }

    public static Integer checkIsAdmin(){
        // 判断当前用户是否是管理员
        User currentUser = UserThreadLocal.get();
        return currentUser.getIsAdmin();
    }
}
